package com.iplant.base.utils.sql;

import java.sql.Connection;
import java.sql.SQLException;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.alibaba.druid.pool.DruidDataSource;
import com.iplant.base.po.enums.DBEnumType;
import com.iplant.base.utils.BaseConfigConstans;
import com.iplant.base.utils.general.LockHelper;

@Component
public class DBDruidHelper implements DisposableBean {

	private static Logger logger = LoggerFactory.getLogger(DBDruidHelper.class);

	private static LockHelper mLockHelper = LockHelper.getLock("DBDruidHelper");

	private static DBDruidHelper Instance = null;

	public static DBDruidHelper getInstance() {
		if (Instance == null) {

			synchronized (mLockHelper) {
				if (Instance == null) {
					Instance = new DBDruidHelper();
				}
			}
		}

		return Instance;
	}

	@PostConstruct
	public void init() {
		Instance = this;
		Instance.MySqlDataSource = this.MySqlDataSource;
		Instance.SqlServerDataSource = this.SqlServerDataSource;
		Instance.OracleDataSource = this.OracleDataSource;

	}

	@Autowired
	@Qualifier("MySqlDataSource")
	private DataSource MySqlDataSource;

	@Autowired
	@Qualifier("SqlServerDataSource")
	private DataSource SqlServerDataSource;

	@Autowired
	@Qualifier("OracleDataSource")
	private DataSource OracleDataSource;

//	private static DataSource MySqlDataSource = null;
//
//	private static DataSource GetMySqlDataSource() {
//		if (MySqlDataSource == null) {
//			synchronized (mLockHelper) {
//				if (MySqlDataSource == null) {
//					MySqlDataSource = new DruidDataSource("MySql_dataSource");
//				}
//			}
//		}
//
//		return MySqlDataSource;
//	}
//
//	private static DataSource AccessDataSource = null;
//
//	private static DataSource GetAccessDataSource() {
//		if (AccessDataSource == null) {
//			synchronized (mLockHelper) {
//				if (AccessDataSource == null) {
//					AccessDataSource = new DruidDataSource("Access_dataSource");
//				}
//
//			}
//
//		}
//
//		return AccessDataSource;
//	}
//
//	private static DataSource OracleDataSource = null;
//
//	private static DataSource GetOracleDataSource() {
//		if (OracleDataSource == null) {
//			synchronized (mLockHelper) {
//				if (OracleDataSource == null) {
//					OracleDataSource = new DruidDataSource("Oracle_dataSource");
//				}
//			}
//		}
//
//		return OracleDataSource;
//	}
//
//	private static DataSource SQLServerDataSource = null;
//
//	private static DataSource GetSQLServerDataSource() {
//		if (SQLServerDataSource == null) {
//			synchronized (mLockHelper) {
//				if (SQLServerDataSource == null) {
//					SQLServerDataSource = new DruidDataSource("SQLServer_dataSource");
//				}
//			}
//
//		}
//		return SQLServerDataSource;
//	}

	private DBEnumType DBType = DBEnumType.getEnumType(BaseConfigConstans.DBServerType);

	public Connection getConnection(DBEnumType wDBType) throws SQLException {

		DataSource wDataSource = getDataSource(wDBType);
		return wDataSource.getConnection();

	}

	public DataSource getDataSource() {

		return getDataSource(DBType);
	}

	public DataSource getDataSource(DBEnumType wDBType) {
		DataSource wResult = null;

		switch (wDBType) {
		case Default:
			wResult = getMySqlDataSource();
			break;
		case Access:
			// wResult = getAccessDataSource();
			wResult = getMySqlDataSource();
			break;
		case MySQL:
			wResult = getMySqlDataSource();
			break;
		case Oracle:
			wResult = getOracleDataSource();
			break;
		case SQLServer:
			wResult = getSqlServerDataSource();
			break;
		default:
			wResult = getMySqlDataSource();
			break;
		}
		return wResult;
	}

	public ShrisJdbcTemplate getTemplate() {

		return new ShrisJdbcTemplate(getDataSource(DBType), DBType);
	}

	public ShrisJdbcTemplate getTemplate(DBEnumType wDBEnumType) {

		return new ShrisJdbcTemplate(getDataSource(wDBEnumType), wDBEnumType);
	}

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub

		try {
			if (MySqlDataSource != null && MySqlDataSource instanceof DruidDataSource) {
				((DruidDataSource) MySqlDataSource).close();
			}
		} catch (Exception e) {
			logger.error("MySqlDataSource destroy", e);
		}
		try {
//			if (AccessDataSource != null && AccessDataSource instanceof DruidDataSource) {
//				((DruidDataSource) AccessDataSource).close();
//			}
		} catch (Exception e) {
			logger.error("AccessDataSource destroy", e);
		}
		try {
			if (OracleDataSource != null && OracleDataSource instanceof DruidDataSource) {
				((DruidDataSource) OracleDataSource).close();
			}
		} catch (Exception e) {
			logger.error("OracleDataSource destroy", e);
		}
		try {
			if (SqlServerDataSource != null && SqlServerDataSource instanceof DruidDataSource) {
				((DruidDataSource) SqlServerDataSource).close();
			}
		} catch (Exception e) {
			logger.error("SQLServerDataSource destroy", e);
		}

	}

	public DataSource getMySqlDataSource() {

		return MySqlDataSource;
	}

	public DataSource getSqlServerDataSource() {
		return SqlServerDataSource;
	}

	public DataSource getOracleDataSource() {
		return OracleDataSource;
	}

}
